Skip to content

Fix initializr localization bundle path (NPE in MyAppName.init)#4852

Merged
shai-almog merged 5 commits into
masterfrom
fix-initializr-l10n-bundles
May 2, 2026
Merged

Fix initializr localization bundle path (NPE in MyAppName.init)#4852
shai-almog merged 5 commits into
masterfrom
fix-initializr-l10n-bundles

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

  • Fixes the NullPointerException in Resources.getL10N when running an initializr project generated with the Include localization bundles option. The bundles were written to common/src/main/resources/ but the CN1 maven plugin's CSS compiler scans common/src/main/l10n/ (or i18n/), so they were never baked into theme.res. Moving them to src/main/l10n/ makes the data actually present in the resource file at runtime.
  • Hardens the framework's Resources.getL10N / listL10NLocales / l10NLocaleSet to return null instead of NPE-ing when the bundle id is missing -- defensive across all projects, not just initializr ones.
  • Strengthens initializr CI so the regression can't ship again: the matrix test asserts bundles land under l10n/ (and explicitly not under resources/), and the integration build test opens theme.res after mvn compile and verifies the messages L10N data is present for default + Hebrew locales.
  • While here, the simulator's CSS watcher / component tree inspector now prefer the version-pinned designer jar from m2 (resolved via the running codenameone-core jar's path) over ~/.codenameone/designer_1.jar, with a clear warning on the legacy fallback. The build-time CSS goal already pinned via getDesignerJar(); this only changes the simulator runtime path.
  • CompileCSSMojo forks the CSS compiler with INFO log level instead of DEBUG so subprocess stack traces are visible without -X. Addresses the diagnosability gap behind issue Unable to launch simulator because of Java.lang.StringIndexOutOfBoundsException in latest as of reporting (7.0.236) #4850 (does not fix that bug -- the underlying CSS compiler exception is still in there, but next report will arrive with a usable stack trace).
  • The four initializr pom templates (barebones, kotlin, grub, tweet) replace skipexisting=\"true\" with usetimestamp=\"true\" on the UpdateCodenameOne.jar download so the bootstrapper refreshes when newer instead of pinning forever.

Files changed

  • CodenameOne/src/com/codename1/ui/util/Resources.java -- null-safe getL10N / listL10NLocales / l10NLocaleSet.
  • Ports/JavaSE/src/.../util/MavenUtils.java -- new findDesignerJarInM2() helper.
  • Ports/JavaSE/src/.../CSSWatcher.java, ComponentTreeInspector.java -- prefer m2 designer over home-dir fallback.
  • maven/codenameone-maven-plugin/.../CompileCSSMojo.java -- INFO log level for CSS subprocess.
  • scripts/initializr/.../GeneratorModel.java -- bundles to src/main/l10n/; bootstrap null/locale fallback.
  • scripts/initializr/.../{barebones,kotlin,grub,tweet}-pom.xml -- usetimestamp on updater download.
  • scripts/initializr/.../GeneratorModelMatrixTest.java -- assert l10n/ location, reject resources/.
  • scripts/initializr/.../GeneratorModelIntegrationBuildTest.java -- post-compile assertion that theme.res actually contains the messages bundle.
  • tests/core/src/com/codename1/ui/util/ResourcesL10NTest.java (new) -- framework regression test for null-safe lookups.

Test plan

  • cd scripts/initializr && ./mvnw -pl common test -- matrix + integration tests pass; integration build verifies theme.res content.
  • cd maven && mvn -Plocal-dev-javase -pl javase -am compile -- JavaSE port compiles.
  • cd maven && mvn -Plocal-dev-javase -pl codenameone-maven-plugin -am compile -- plugin compiles.
  • Manually generate a barebones project with Include localization bundles enabled, mvn cn1:run -- simulator starts without the previously-reported NPE; on a non-Hebrew/Arabic device the default messages.properties fallback is applied.
  • Verify a project run that previously fell back to ~/.codenameone/designer_1.jar now logs the m2 path (or the warning if no m2 designer is available).

🤖 Generated with Claude Code

The initializr's "include localization bundles" option generated bundles
under common/src/main/resources/messages*.properties, but the CN1 maven
plugin's CSS compiler scans common/src/main/l10n (or i18n) for bundles to
bake into theme.res. The result: Resources.getGlobalResources().getL10N(
"messages", lang) hit a missing resource id at simulator startup and
threw NPE in MyAppName.init -- the project couldn't run.

- GeneratorModel.addLocalizationEntries: write to src/main/l10n so the
  bundles actually end up inside theme.res.
- Bootstrap (Java + Kotlin) injected into the starter class is now
  null-safe and falls back to the default locale when the device
  language has no specific bundle.
- Resources.getL10N / listL10NLocales / l10NLocaleSet now return null
  instead of NPE-ing when the bundle id is absent. Defensive change at
  the framework level so any project shipping mismatched bundles
  degrades gracefully.
- New tests/core/.../ResourcesL10NTest covers the framework null-safety.
- GeneratorModelMatrixTest now asserts bundles land under l10n and are
  NOT under src/main/resources (catches the regression at unit-test
  time).
- GeneratorModelIntegrationBuildTest now opens common/target/classes/
  theme.res after mvn compile and verifies "messages" L10N data is
  present for both the default ("") and Hebrew ("he") locales -- the
  end-to-end signal the previous tests missed.

While here, harden the simulator's CSS compiler invocation against
stale ~/.codenameone/designer_1.jar:

- New MavenUtils.findDesignerJarInM2 derives the running CN1 version
  from the codenameone-core jar's m2 path and resolves the matching
  codenameone-designer-<version>-jar-with-dependencies.jar. Any plugin
  invocation has already pulled this into m2 as a plugin dependency.
- CSSWatcher and ComponentTreeInspector now prefer codename1.designer.jar
  -> m2 designer -> ~/.codenameone fallback (with a clear warning when
  the legacy fallback is hit). The build-time CSS goal already used
  getDesignerJar() so this only affects the simulator runtime / live
  CSS reload paths.
- CompileCSSMojo now invokes the forked CSS compiler with INFO log
  level instead of DEBUG so subprocess stack traces are visible without
  re-running with -X. This won't fix issue #4850 but makes the next
  similar report actionable.
- The four initializr pom templates replace skipexisting="true" with
  usetimestamp="true" on the UpdateCodenameOne.jar download so future
  installs refresh the updater jar instead of pinning forever to the
  first copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 2, 2026

Compared 7 screenshots: 7 matched.
✅ JavaSE simulator integration screenshots matched stored baselines.

The previous patch raised the CSS subprocess log level by passing it
explicitly at the call site (createJava(LEVEL_INFO)), which bypasses
CompileCSSMojoTest's TestCompileCSSMojo.createJava() override -- the
test substitutes a RecordingJava there to capture the command line
without forking. The override was no longer hit, so the test fell
through to a real fork against a stub designer.jar and four tests
errored out with "Invalid or corrupt jarfile".

Move the INFO log level into a createJava() override on CompileCSSMojo
itself. The call site stays at createJava(), so the test override
continues to win, and production still gets INFO so subprocess stack
traces remain visible without -X.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Cloudflare Preview

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 2, 2026

Compared 86 screenshots: 86 matched.

Native Android coverage

  • 📊 Line coverage: 9.87% (5367/54363 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.75% (26316/339620), branch 3.59% (1169/32596), complexity 4.55% (1419/31207), method 7.97% (1162/14574), class 13.02% (254/1951)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.87% (5367/54363 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.75% (26316/339620), branch 3.59% (1169/32596), complexity 4.55% (1419/31207), method 7.97% (1162/14574), class 13.02% (254/1951)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 901.000 ms
Base64 CN1 encode 124.000 ms
Base64 encode ratio (CN1/native) 0.138x (86.2% faster)
Base64 native decode 794.000 ms
Base64 CN1 decode 318.000 ms
Base64 decode ratio (CN1/native) 0.401x (59.9% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 2, 2026

iOS screenshot updates

Compared 86 screenshots: 85 matched, 1 updated.

  • landscape — updated screenshot. Screenshot differs (2556x1179 px, bit depth 8).

    landscape
    Preview info: Preview provided by instrumentation.
    Full-resolution PNG saved as landscape.png in workflow artifacts.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 180 seconds

Build and Run Timing

Metric Duration
Simulator Boot 58000 ms
Simulator Boot (Run) 1000 ms
App Install 13000 ms
App Launch 3000 ms
Test Execution 270000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1040.000 ms
Base64 CN1 encode 1343.000 ms
Base64 encode ratio (CN1/native) 1.291x (29.1% slower)
Base64 native decode 757.000 ms
Base64 CN1 decode 962.000 ms
Base64 decode ratio (CN1/native) 1.271x (27.1% slower)
Base64 SIMD encode 396.000 ms
Base64 encode ratio (SIMD/native) 0.381x (61.9% faster)
Base64 encode ratio (SIMD/CN1) 0.295x (70.5% faster)
Base64 SIMD decode 435.000 ms
Base64 decode ratio (SIMD/native) 0.575x (42.5% faster)
Base64 decode ratio (SIMD/CN1) 0.452x (54.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 80.000 ms
Image createMask (SIMD on) 14.000 ms
Image createMask ratio (SIMD on/off) 0.175x (82.5% faster)
Image applyMask (SIMD off) 127.000 ms
Image applyMask (SIMD on) 74.000 ms
Image applyMask ratio (SIMD on/off) 0.583x (41.7% faster)
Image modifyAlpha (SIMD off) 141.000 ms
Image modifyAlpha (SIMD on) 72.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.511x (48.9% faster)
Image modifyAlpha removeColor (SIMD off) 147.000 ms
Image modifyAlpha removeColor (SIMD on) 64.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.435x (56.5% faster)
Image PNG encode (SIMD off) 987.000 ms
Image PNG encode (SIMD on) 824.000 ms
Image PNG encode ratio (SIMD on/off) 0.835x (16.5% faster)
Image JPEG encode 592.000 ms

shai-almog and others added 3 commits May 2, 2026 20:02
The user shared the missing stack trace from issue #4850:

  at java.base/java.lang.String.substring(String.java:2899)
  at com.codename1.ui.plaf.UIManager.parseTextFieldInputMode(UIManager.java:2434)
  at com.codename1.ui.plaf.UIManager.setBundle(UIManager.java:2419)
  at com.codename1.impl.javase.JavaSEPort.enableAutoLocalizationBundle(...)
  at com.codename1.impl.javase.JavaSEPort.init(JavaSEPort.java:5598)
  at com.codename1.impl.CodenameOneImplementation.initImpl(...)
  at com.codename1.ui.Display.init(Display.java:351)
  at com.codename1.designer.css.CN1CSSCLI.main(CN1CSSCLI.java:713)

This is not a path-related bug -- every initializr-generated project hits
it at css-goal time. Three pieces interact:

1. JavaSEPort.findLocalizationDirectory auto-creates src/main/l10n if it
   is missing, and enableAutoLocalizationBundle installs an
   AutoLocalizationBundle for it.
2. AutoLocalizationBundle.get echoes any missing key back as its own
   value -- the simulator's "wormhole" so devs can spot untranslated
   strings.
3. UIManager.setBundle queries "@im" on every bundle install. With the
   echo behavior, "@im" -> "@im", which is then tokenized to ["@im"],
   "@im-@im" is queried (which echoes "@im-@im"), and
   parseTextFieldInputMode crashes on substring(0, indexOf('=')) because
   that token has no '=' (range [0, -1) of length 7).

The CSS compiler subprocess inherits all of this because CN1CSSCLI.main
calls Display.init -> JavaSEPort.init -> enableAutoLocalizationBundle.

Fixes:

- AutoLocalizationBundle.get returns null for keys starting with '@'.
  Meta-keys (@rtl, @im, @im-<name>) are configuration entries that
  callers distinguish from "missing" by checking for null. Echoing the
  key back is semantically wrong AND broke setBundle. Real meta-key
  values that exist in the underlying file (e.g. @rtl=true in a Hebrew
  bundle) are still returned -- only fabrication is suppressed.
- UIManager.parseTextFieldInputMode skips tokens without '=' and skips
  entries whose key isn't a valid integer. Defensive belt-and-suspenders
  so any bundle with malformed input-mode entries degrades gracefully
  instead of failing the whole bundle install.
- New UIManagerSetBundleTest exercises setBundle against an echo-bundle
  (matches pre-fix AutoLocalizationBundle behavior) and against directly
  malformed @im/@im-x entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… fix

Per review: silently skipping malformed `@im` tokens hides legitimate
bugs in user-supplied bundles. Real malformed input should fail loudly,
not be swallowed.

The actual root cause -- AutoLocalizationBundle fabricating values for
@-prefixed meta-keys -- stays fixed. That's the surgical change: the
auto-localize wormhole was returning fake values for keys that callers
explicitly use null/non-null to gate features (@im, @rtl, @im-<name>),
which is semantically wrong and broke setBundle.

Moves the regression coverage from the no-op stub in core to the
existing AutoLocalizationBundleTest in the JavaSE port (where the bundle
class actually lives), asserting:
- @-prefixed meta-keys are NOT auto-fabricated
- @-prefixed meta-keys that exist in the underlying file ARE returned

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…wormhole

Workaround for the AutoLocalizationBundle @im fabrication crash in
shipped Codename One <= 7.0.236. The proper fix lives in JavaSEPort
(don't fabricate values for `@`-prefixed meta-keys) and is on this
branch, but it requires a new framework release. Until then, every
initializr-generated project crashes at css-goal time inside the CSS
compiler subprocess (CN1CSSCLI -> Display.init -> JavaSEPort.init ->
enableAutoLocalizationBundle -> UIManager.setBundle ->
parseTextFieldInputMode on substring(0, -1) for "@im-@im").

Ship `common/src/main/l10n/Bundle.properties` with a single `@im=`
entry on every generated project. Two reasons it works:

1. JavaSEPort.findDefaultLocalizationBundleFile prefers Bundle.properties
   over any other file in src/main/l10n, so the AutoLocalizationBundle
   loads our stub as its base.
2. With `@im=""` already in the bundle's underlying Hashtable,
   AutoLocalizationBundle.get("@im") returns "" instead of fabricating
   "@im". setBundle sees length 0 and skips the input-mode block, so
   parseTextFieldInputMode is never called.

The stub is unconditional (added to every project, with or without
localization bundles enabled) because the bug fires regardless --
enableAutoLocalizationBundle auto-creates src/main/l10n in the CSS
compiler subprocess even on projects that didn't request localization.

The matrix test asserts the stub is present on every generated project
combination so this workaround can't silently regress.

Once the AutoLocalizationBundle fix lands in a release and the
initializr is bumped past it, this stub can be removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit 25dbe3e into master May 2, 2026
22 checks passed
shai-almog added a commit that referenced this pull request May 12, 2026
… jar (#4929)

* Fix CSSWatcher live reload: drop stale bindings + extract m2 designer jar

Two recent CSS/localization changes regressed the simulator's live CSS
reload, in different ways.

1. addThemeProps stomped user edits with stale @cn1-bind entries.
   PR #4884 added applyThemeBindings() inside UIManager.buildTheme so a
   single addThemeProps({"@accent-color": ...}) override could retune
   every var()-bound theme key. But CSSWatcher reloads the theme through
   the same code path -- and addThemeProps never clears themeConstants.
   When the user replaced a `var()` rule with a literal in their CSS,
   the recompiled theme.res no longer emitted the matching
   `@cn1-bind:<key>` entry, but the previous binding was still sitting
   in themeConstants. applyThemeBindings happily re-overlaid the
   user's fresh literal value with the stale binding's resolved value,
   so the visible change disappeared on every reload.

   Fix: in buildTheme, before iterating the incoming Hashtable, detect
   any binding whose subject style key the new load is re-setting
   without re-asserting the binding alongside, and drop those bindings
   before the overlay pass runs. Pure `@accent-color` overrides keep
   working because they don't carry style keys, so no bindings are
   considered stale.

2. MavenUtils.findDesignerJarInM2 returned the unrunnable wrapper zip.
   PR #4852 added an m2 fallback for the CSSWatcher's designer-jar
   lookup, used whenever -Dcodename1.designer.jar isn't passed in (e.g.
   simulator launched from the IDE rather than `mvn cn1:run`). The
   helper returned `codenameone-designer-<v>-jar-with-dependencies.jar`
   directly from m2 -- but that artifact is a zip wrapper containing a
   single inner designer_1.jar (see maven/designer/pom.xml's antrun
   step), with no top-level Main-Class manifest. `java -jar wrapper.zip`
   fails with "no main manifest attribute", the CSS subprocess never
   starts, and the watcher silently waits for ::refresh:: lines that
   never come.

   Fix: mirror AbstractCN1Mojo.getDesignerJar's pattern -- unzip the
   wrapper to an `<artifact>.jar-extracted/` sibling on demand and
   return the inner designer_1.jar so `java -jar` actually launches.

Tests:

- UIManagerThemeBindingsTest gains three regression cases:
  cssReloadDropsStaleBindingWhenRuleBecomesLiteral (the actual
  reproducer), cssReloadKeepsBindingWhenStillEmittedTogether (guard
  against an over-eager fix), and overrideOnlyReloadKeepsBindings
  (repeated `@accent-color` retunes still work). The first fails
  before the UIManager fix; all three pass after.

- MavenUtilsTest is new and covers the wrapper-vs-inner-jar resolution
  with five cases: happy path, re-use of extracted inner jar when the
  wrapper hasn't changed, re-extract when the wrapper mtime advances,
  null when the core jar isn't in an m2 layout, and null when the
  designer artifact is missing. To make these actually executable, the
  javase pom now pins maven-surefire-plugin to 3.2.5 (the parent's
  2.21.0 doesn't auto-discover JUnit Jupiter). The pre-existing
  CSSWatcherTest + LocationSimulationTest + JavaSEPortFontMappingTest
  in the same module also start running as a side effect.

- pr.yml gets a new "Run JavaSE port unit tests" step so this whole
  test class -- which compiled but never executed -- is wired into CI.
  Without it, regressions in CSSWatcher/MavenUtils/JavaSEPort helpers
  would continue to slip through, which was the original gap the user
  flagged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Address PR review: harden Zip Slip + install javase deps in CI step

- MavenUtils.extractInnerJar no longer derives a File path from
  ZipEntry.getName(). CodeQL flagged the previous loop as a Zip Slip
  risk because a wrapper containing `../../etc/passwd` would have been
  written outside the extraction directory. The wrapper produced by
  maven/designer/pom.xml has a single designer_1.jar entry by design,
  so the extractor now (a) writes only to a single fixed destination
  path under destDir and (b) only matches entries whose literal name
  equals "designer_1.jar". Anything else is skipped; if the canonical
  entry is absent, the method throws. Two new MavenUtilsTest cases:
  refusesPathTraversalEntriesAndDoesNotWriteOutsideExtractDir packs a
  `../../escaped.txt` entry and asserts no escaped file appears in the
  temp root; skipsUnexpectedEntriesAndStillExtractsDesignerJar mixes
  a README and a subdir/other.jar with the real designer_1.jar and
  asserts only the inner jar lands on disk.

- pr.yml's new "Run JavaSE port unit tests" step failed with
  "Could not find artifact com.codenameone:sqlite-jdbc:jar:8.0-SNAPSHOT"
  on all three matrix entries (Java 8/17/21). The earlier "Build
  Codename One" step builds core-unittests with -am, which doesn't
  install sqlite-jdbc into the local repo. Split the new step into
  two mvn invocations: first install javase's transitive deps without
  running their tests, then run javase's tests in isolation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* UIManager: scope stale-binding drop to addThemeProps, fix iOS hang

The previous fix ran the stale-binding preprocessing inside buildTheme,
which is also called from the @includeNativeBool layered initial load
(setThemePropsImpl -> buildTheme -> Display.installNativeTheme() ->
buildTheme(native) -> outer buildTheme(userTheme) continues). After the
native theme installs its bindings into themeConstants, the outer call's
preprocessing would drop them whenever the user's app theme.css set a
literal value for the same UIID -- which the existing iOS / Android
screenshot goldens were captured against.

The iOS PR check hit this: the device-runner log shows the suite ran
fine through ChartCubicLineScreenshotTest and then hung in
ChartBarScreenshotTest setup until the 30-minute timeout fired. The
inconsistent themeConstants state left over once the layered native
bindings were dropped manifests as a hang in chart-component initialization
(presumably a Style.derive cycle or similar) rather than as a pixel
diff.

Move the drop pre-pass out of buildTheme and into a new
dropSupersededBindings() called only from addThemeProps. This keeps
the CSSWatcher reload fix (the actual reported regression) and the
companion regression tests passing, while restoring the original
behavior of the layered initial-load path -- bindings declared by the
native theme via @includeNativeBool stay live, user-app literals don't
silently strip them out.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant